//
//  RefreshManager.swift
//  RssFly
//
//  Created by shen on 2023/10/17.
//

import CoreData

final class RefreshManager {
    static func refresh(profile: Profile, session _: URLSession = .shared) async {
        await MainActor.run {
            NotificationCenter.default.post(name: .refreshStarted, object: profile.objectID)
        }

        var feedUpdateTasks: [FeedUpdateTask] = []
        for feed in profile.feedsArray {
            if let url = feed.url {
                feedUpdateTasks.append(
                    FeedUpdateTask(
                        feedObjectID: feed.objectID,
                        pageObjectID: feed.page?.objectID,
                        profileObjectID: feed.page?.profile?.objectID,
                        url: url,
                        updateMeta: feed.needsMetaUpdate
                    )
                )
            }
        }

        let maxConcurrency = min(4, ProcessInfo().activeProcessorCount)

        _ = await withTaskGroup(of: Void.self, returning: Void.self, body: { taskGroup in
            var working = 0
            for task in feedUpdateTasks {
                if working >= maxConcurrency {
                    await taskGroup.next()
                    working = 0
                }
                taskGroup.addTask { _ = await task.execute() }
                working += 1
            }
            await taskGroup.waitForAll()
        })

        await MainActor.run {
            NotificationCenter.default.post(name: .refreshProgressed, object: profile.objectID)
        }

        await AnalyzeTask(profileObjectID: profile.objectID).execute()

        RefreshedDateStorage.setRefreshed(profile, date: .now)

        await MainActor.run {
            NotificationCenter.default.post(name: .refreshFinished, object: profile.objectID)
        }
    }

    static func refresh(feed: Feed, session _: URLSession = .shared) async {
        if let url = feed.url {
            let feedUpdateTask = FeedUpdateTask(
                feedObjectID: feed.objectID,
                pageObjectID: feed.page?.objectID,
                profileObjectID: feed.page?.profile?.objectID,
                url: url,
                updateMeta: true
            )
            _ = await feedUpdateTask.execute()
        }
    }
}
